/*Designed by Cassy, 53755787 2024.9.26


*/

#include "main.h"
#include "cw32l010_sysctrl.h"
#include "init.h"
#include "global.h"
#include "motor.h"
#include "compu.h"
#include "control.h"
#include "sensorless.h"

void PowerOnDelay(void)
{
	unsigned int i;
		
	for(i=0;i<60000;i++);
	for(i=0;i<60000;i++);
	for(i=0;i<60000;i++);
	for(i=0;i<60000;i++);
	for(i=0;i<60000;i++);
	for(i=0;i<60000;i++); 
	
		KKN=(MAXSPEED-MINSPEED);
	  KKN=KKN/(NMAXVD-NMINVD);
		
		KPWMN=PWMMax-PWMMin;
		KPWMN=KPWMN/(NMAXVD-NMINVD);
	
		KKPWM=(MAXOUTP-MINOUTP);
	  KKPWM=KKPWM/(PWMmax-PWMmin);	
}

void PPMCheck(void)
{
	unsigned char cc=0,i,j;
	
	//连续检测电位器检测，10次中有8次不归零，让为故障
	  for(i=0;i<10;i++)
	   { 
			 SamplePWMSpeed();		
	     if(SetSpeed!=0)cc++;
			 for(j=0;j<20;j++);
		 }
		 if(cc>8)ErrorCode=10; //上电电位器不归零	  
}

unsigned int ov=0;
unsigned int timex=0;
void PPMGPIOINIT_Config(void)
{ 
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    __SYSCTRL_GPIOA_CLK_ENABLE();    // 使能GPIO的配置时钟

    GPIO_InitStruct.IT = GPIO_IT_RISING | GPIO_IT_FALLING;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pins = GPIO_PIN_5;
    GPIO_Init(CW_GPIOA, &GPIO_InitStruct);  

    GTIM1_Configuration();
    CW_GTIM1->CNT = 0; 
    GTIM_ITConfig(CW_GTIM1, BTIM_IT_UPDATE, ENABLE); 
    GTIM_Cmd(CW_GTIM1, ENABLE);

    NVIC_EnableIRQ(GTIM1_IRQn); 
    GPIOA_INTFLAG_CLR(bv5);	 //清除PA05中断标志并使能NVIC
    NVIC_EnableIRQ(GPIOA_IRQn);	
}


void GPIOA_IRQHandler(void)
{
  if (CW_GPIOA->ISR_f.PIN5)
  { 
		 if(GPIO_ReadPin(CW_GPIOA,GPIO_PIN_5)==GPIO_Pin_RESET)
		 {
			 GTIM_Cmd(CW_GTIM1, DISABLE);
			 if(ov!=0)timex=0xffff;
			 else timex=CW_GTIM1->CNT;			 
	   }
		 else if(GPIO_ReadPin(CW_GPIOA,GPIO_PIN_5)==GPIO_Pin_SET)
		 {
			 ov=0;CW_GTIM1->CNT=0;
			GTIM_Cmd(CW_GTIM1, ENABLE);
	   }
		
		 GPIOA_INTFLAG_CLR(bv5);  
  }
}

void GTIM1_IRQHandler(void)
{
    /* USER CODE BEGIN */
    if (GTIM_GetITStatus(CW_GTIM1, GTIM_IT_UPDATA))
    {
        GTIM_ClearITPendingBit(CW_GTIM1, GTIM_IT_UPDATA);
			  ov++;
    }
    /* USER CODE END */
}

 unsigned int hte=0;
int main(void)
{		
	unsigned char DZCount=0;	
	
	PowerOnDelay();
  RCC_Configuration();
	DPWMConfiguration();	
	RST_KEYConfiguration();
	ADC_Configuration();
	BLDC_Configuration();
	BTIM1_Configuration(); 
	SENSORLESS_TIM_Config(); 
	
	PowerOnDelay(); //延时，等系统电源稳定后，获取电流偏置
	if(SampleData[5]>750&&SampleData[5]<=900)DIin=SampleData[5];	 //计算电流偏置
	
	PPMGPIOINIT_Config();
	TimeCountCompuSpeed=0;
	while(TimeCountCompuSpeed<50);
	TimeCountCompuSpeed=0;
	PPMCheck();
  while (1)
	{
		  if(TimeCountCompuSpeed>20) //20MS采集一次速度设定值,并检查HALL是否有误
	       {
					 TimeCountCompuSpeed=0; 
						SamplePWMSpeed();				 					 
	       }
				 
			if(TimeCountVI>=100)//100MS计算一次电压电流,并作一次实时速度计算
		  {
			 TimeCountVI=0;
			 SampleVI();
			 			  
			 	RealS=hte*100/MPolePairs;//HALLcount1*10*60/6/MPolePairs; 100MS存储一次霍尔边沿数							
			  if(MOTORSTATE==STATESTARTPID||MOTORSTATE==STATERUNPID||MOTORSTATE==STATESTARTOPEN||MOTORSTATE==STATERUNOPEN)
				 {
						if(RealS<200)
						{
							 DZCount++;
							 if(DZCount>=20)//2S保护
							 { 								
									DZCount=0;ErrorCode=7;//堵转							 
								}
						}
						else DZCount=0;
					}
		  }		
		
		  if(ErrorCode!=0&&MOTORSTATE!=STATEERROR&&MOTORSTATE!=STATEERROROVER)//发生故障
		  {  
				  MOTORSTATE=STATEERROR;
    	}
			 
			switch(MOTORSTATE)
		 {
			 case STATESTARTCHECK:  
				 
				    MotorStartCheck();			      
						break;
			 case STATESTARTDELAY:
						MotorStartDealy();
						DirCheck();
						break;
			 case STATESTARTOPEN:
						MotorStartOPEN();		
						DirCheck();
			      break;			
			 case STATERUNOPEN: 
						MotorRunOPEN();
						DirCheck();
						break;						 
			 case STATESTOP: MotorStop();break;
			 case STATEERROR: MotorError();break;
			 case STATEERROROVER: MotorErrorOver();break;
			 case STATWAITSTART:WaitStart();break;
	   }			
	}
}

void BTIM1_IRQHandler(void)
{
  /* USER CODE BEGIN */
  if (BTIM_GetITStatus(CW_BTIM1, BTIM_IT_UPDATE))
  {
     BTIM_ClearITPendingBit(CW_BTIM1, BTIM_IT_UPDATE); 

			if(StOk==1)
		 {
			 Timesensor++;
			 if(Timesensor>=25) //25ms没换相，则强制换相 4对极100RPM
				{
					Timesensor=0;
					
					if(Dir==1)
							 {
									bHallStartStep1++;
									if(bHallStartStep1>=6)bHallStartStep1=0;
							 }
							 else 
								{
									if(bHallStartStep1==0)bHallStartStep1=5;
									else bHallStartStep1--;
								}
								
						Commutation(bHallStartStep1,Motor_Start_F); 				
				}
			}
		 else Timesensor=0;
						 
						 
		TimeCountTemp++;		//临时计时用
		TimeCountCompuSpeed++; //计算设定速度
    TimeCountSTDelay++;		//启动延时
			
		TimeCountRealSpd++; //瞬时速度计明用
		if(TimeCountRealSpd>=20){HALLcountTemp=HALLcount;HALLcount=0;TimeCountRealSpd=0;}
		
	  TimeCountPID++; //PID定时计数用		
		TimeCountAvgSpd++;	//平均速度计数用
		if(TimeCountAvgSpd>=100){hte=HALLcount1;HALLcount1=0;TimeCountAvgSpd=0;}//用于显示的速度值或堵转保护的速度		 
		TimeCountStartUP++; //电机启动过程时，加速计数计时用		 
		TimeCountVI++;//计算电压电流
	}
  /* USER CODE END */
}
/******************************************************************************
 * EOF (not truncated)
 ******************************************************************************/
#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
    /* USER CODE BEGIN 6 */
    /* User can add his own implementation to report the file name and line number,
       tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
    /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

